---
title: 并发编程
---
**并发、并行、多任务、多进程、多线程、分布式系统**

* 并发是指如何正确、高效地控制共享资源；
* 并行是指如何利用更多的资源来产生快速的响应。
* 分布式系统是指会有其它机器帮助处理任务。

**并发，同时处理多个任务，即不必等待一个任务完成就能开始处理其他任务。并发解决的是阻塞问题，即一个任务必须要等待非其可控的外部条件满足后才能继续执行，最常见的例子是 I/O，一个任务必须要等待输入才能继续执行（即被阻塞），类似地场景称为 I/O 密集型问题。**

**并行, 同时在多处执行多个任务。并行解决的是计算密集型地任务，即通过把任务分成多个部分，并在多个处理器上执行，从而提升程序运行地速度。**

两者地关键都是 “同时处理多个任务”，而并行则额外包括了多处理器分布式处理地概念。

两者解决地不是同一类型地问题: 对于 I/O 密集型的问题，并行可能起不到什么明显的作用，因为瓶颈不在于速度，而在于阻塞；而对于计算密集型问题，如果想用并发在单处理器上解决，则多半会徒劳无功。

很多编程语言使用了相同的机制————线程————来实现并发和并行。


并发是**一系列聚焦于如何减少等待并提升性能的技术**

* 它是一个集合：有多种方法可以解决问题。
* 是关于性能的技术，最有遇到重大的性能问题的时候才考虑使用。
* 关于减少等待这一点非常重要，不管运行在多少处理器上，只有某种等待产生了，优化才有收益。

即使是单处理器系统，并发也能带来好处，它可以从一个等待中（被阻塞）的任务切换到另一个已经准备好的任务。但是如果所有的任务都能永远运行不被阻塞，那么切换任务的损耗反而会使整个系统慢下来。这时，并发只能在确实拥有多处理器时才有意义。

并发编程会带来风险，除非确定别无选择。

如果希望程序跑的快点，那就可以将程序拆分成片段，然后将片段放到独立的处理器上运行。随着处理器时钟频率的提升变得越来越困难,相较于单纯提升芯片速度，速度的提升越来越倾向多处理器并行的方向。

利用多处理器机器，可以将多任务分发到这些处理器上，这将显著提升吞吐量。这是多核 Web 服务器常用的方案，它们可以通过程序为每一个请求分配一个线程，从而将大量的用户请求分发到多个 CPU 上。

:::tip
上下文切换（context switch，在任务之间切换）会导致额外的开销。
:::

:::tip
操作系统通常会将各个进程相互隔离，因此不会互相干扰；多线程会共享如内存和 I/O 等资源，因此，编写多线程的难点之一便是在各个线程驱动的任务间调度这些资源，使其同一时刻只能被一个任务访问。

多进程通常存在数量和开销限制，这影响了多进程在并发领域的适用性。

有些编程语言的设计是将各个并发任务隔离起来，通常叫做**函数式语言**,其中每个函数的调用都不会产生副作用。
:::



import DocCardList from '@theme/DocCardList';


<DocCardList/>
